package com.gsafety.wellsfort.common.util;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.gsafety.wellsfort.common.constant.OSSConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;


/**
 * 阿里云 OSS文件类
 *
 * @author lingchengshu
 */
@Slf4j
public class OSSClientUtil {

    private static OSS ossClient;


    static {
        ossClient = new OSSClientBuilder().build(OSSConstant.END_INTERNAL_POINT, OSSConstant.ACCESS_KEY_ID, OSSConstant.ACCESS_KEY_SECRET);
    }


    public static String uploadFile(MultipartFile file, boolean async) throws Exception {
        String imgUrl = null;
        try {
            imgUrl = "";
            String path = null;
            if (file != null && !file.isEmpty()) {
                // 获取图片的文件名
                String fileName = file.getOriginalFilename();
                // 获取图片的扩展名
                String extensionName = fileName.substring(fileName.lastIndexOf(".") + 1);
                if (extensionName.endsWith("png") || extensionName.endsWith("jpg") || extensionName.endsWith("jpeg")) {
                    path = "image/";
                } else {
                    path = "file/";
                }
                // 新的图片文件名 =随机数+获取时间戳+"."图片扩展名
                String newsFileName = (int) (Math.random() * 1000) + String.valueOf(System.currentTimeMillis()) + "." + extensionName;
                if (async) {
                    imgUrl = uploadImg2OssAsync(file, path, newsFileName);
                } else {
                    imgUrl = uploadImg2Oss(file, path, newsFileName);
                }
            }
        } catch (Exception e) {
            log.error("exception={}", e);
            throw e;
        } finally {
        }
        return imgUrl;
    }

    public static String uploadImg2Oss(MultipartFile file, String fileDir, String name) throws Exception {
        try {
            InputStream inputStream = file.getInputStream();
            uploadFile2OSS(inputStream, name, fileDir);
            return "https://" + OSSConstant.BUCKET_NAME + "." + OSSConstant.END_POINT + "/" + fileDir + name;
        } catch (Exception e) {
            log.error("exception={}", e);
            throw new Exception("图片上传失败");
        }
    }

    public static String uploadImg2OssAsync(MultipartFile file, String fileDir, String name) throws Exception {
        try {
            InputStream inputStream = file.getInputStream();
            ThreadPoolClient.execute(new Runnable() {
                @Override
                public void run() {
                    uploadFile2OSS(inputStream, name, fileDir);
                }
            });
            return "https://" + OSSConstant.BUCKET_NAME + "." + OSSConstant.END_POINT + "/" + fileDir + name;
        } catch (Exception e) {
            log.error("exception={}", e);
            throw new Exception("图片上传失败");
        }
    }

    /**
     * 上传到OSS服务器 如果同名文件会覆盖服务器上的
     *
     * @param instream 文件流
     * @param fileName 文件名称 包括后缀名
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public static String uploadFile2OSS(InputStream instream, String fileName, String filedir) {
        String ret = "";
        try {
            // 创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getContentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            // 上传文件
            PutObjectResult putResult = ossClient.putObject(OSSConstant.BUCKET_NAME, filedir + fileName, instream, objectMetadata);
            log.info("putResult={}", JSON.toJSONString(putResult));
            ret = putResult.getETag();
        } catch (IOException e) {
            log.error("exception={}", e);
        } finally {
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getContentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") || FilenameExtension.equalsIgnoreCase(".jpg")
                || FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpeg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") || FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") || FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        if (FilenameExtension.equalsIgnoreCase(".xlsx") || FilenameExtension.equalsIgnoreCase(".xls")) {
            return "application/vnd.ms-excel";
        }
        if (FilenameExtension.equalsIgnoreCase(".mp4")) {
            return "video/mpeg4";
        }
        if (FilenameExtension.equalsIgnoreCase(".mpeg")) {
            return "video/mpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".rmvb")) {
            return "application/vnd.rn-realmedia-vbr";
        }
        if (FilenameExtension.equalsIgnoreCase(".mp3")) {
            return "audio/mp3";
        }
        if (FilenameExtension.equalsIgnoreCase(".mp3")) {
            return "audio/mp3";
        }
        if (FilenameExtension.equalsIgnoreCase(".wav")) {
            return "audio/wav";
        }
        return "image/jpeg";
    }
}
